#pragma once

namespace gtl
{

namespace mpl
{

template<int p1, int p2 = 0, int p3 = 0, int p4 = 0, int p5 = 0, int p6 = 0, int p7 = 0, int p8 = 0, int p9 = 0>
struct enum_
{
	enum { count = 9 };
	enum { v1 = p1, v2 = p2, v3 = p3, v4 = p4, v5 = p5, v6 = p6, v7 = p7, v8 = p8, v9 = p9, };
};

template<int p1>
struct enum_<p1, 0, 0, 0, 0, 0, 0>
{
	enum { count = 1 };
	enum { v1 = p1, };
};

template<int p1, int p2>
struct enum_<p1, p2, 0, 0, 0, 0, 0>
{
	enum { count = 2 };
	enum { v1 = p1, v2 = p2, };
};

template<int p1, int p2, int p3>
struct enum_<p1, p2, p3, 0, 0, 0, 0>
{
	enum { count = 3 };
	enum { v1 = p1, v2 = p2, v3 = p3, };
};

template<int p1, int p2, int p3, int p4>
struct enum_<p1, p2, p3, p4, 0, 0, 0>
{
	enum { count = 4 };
	enum { v1 = p1, v2 = p2, v3 = p3, v4 = p4, };
};

template<int p1, int p2, int p3, int p4, int p5>
struct enum_<p1, p2, p3, p4, p5, 0, 0>
{
	enum { count = 5 };
	enum { v1 = p1, v2 = p2, v3 = p3, v4 = p4, v5 = p5,};
};

template<int p1, int p2, int p3, int p4, int p5, int p6>
struct enum_<p1, p2, p3, p4, p5, p6, 0>
{
	enum { count = 6 };
	enum { v1 = p1, v2 = p2, v3 = p3, v4 = p4, v5 = p5, v6 = p6, };
};

template<int p1, int p2, int p3, int p4, int p5, int p6, int p7>
struct enum_<p1, p2, p3, p4, p5, p6, p7, 0, 0>
{
	enum { count = 7 };
	enum { v1 = p1, v2 = p2, v3 = p3, v4 = p4, v5 = p5, v6 = p6, v7 = p7, };
};

template<int p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8>
struct enum_<p1, p2, p3, p4, p5, p6, p7, p8, 0>
{
	enum { count = 8 };
	enum { v1 = p1, v2 = p2, v3 = p3, v4 = p4, v5 = p5, v6 = p6, v7 = p7, v8 = p8, };
};

template<int index, class MTY> struct get;

template<class MTY>	struct get<1, MTY>
{
	enum { value = MTY::v1 };
};

template<class MTY>	struct get<2, MTY>
{
	enum { value = MTY::v2 };
};

template<class MTY>	struct get<3, MTY>
{
	enum { value = MTY::v3 };
};

template<class MTY>	struct get<4, MTY>
{
	enum { value = MTY::v4 };
};

template<class MTY>	struct get<5, MTY>
{
	enum { value = MTY::v5 };
};

template<class MTY>	struct get<6, MTY>
{
	enum { value = MTY::v6 };
};

template<class MTY>	struct get<7, MTY>
{
	enum { value = MTY::v7 };
};

template<class MTY>	struct get<8, MTY>
{
	enum { value = MTY::v8 };
};

template<class MTY>	struct get<9, MTY>
{
	enum { value = MTY::v9 };
};

} // end of namespace mpl

} // end of namespace gtl